package cuishifeng.blog;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;

import com.alibaba.fastjson.JSON;

import cuishifeng.blog.constants.Constants;
import cuishifeng.blog.helper.DateHelper;
import cuishifeng.blog.helper.FileHelper;
import cuishifeng.blog.helper.HtmlHelper;
import cuishifeng.blog.helper.VelocityHelper;
import cuishifeng.blog.markdown.MarkdownParser;
import cuishifeng.blog.model.BlogInfo;
import cuishifeng.blog.model.BlogTitle;
import lombok.extern.slf4j.Slf4j;

/**
 * @author cuishifeng <cuishifeng0207@163.com>
 * Created on 2021-02-03
 */
@Slf4j
public class BlogParseUtils {

    /**
     * 截取博客md内容
     */
    public static BlogInfo getBlogInfo(String fileName) throws IOException {
        File file = FileHelper.getFile("md/" + fileName);
        String md = IOUtils.toString(file.toURI(), Charset.forName("utf-8"));
        String[] heads = md.split("---", 3);
        return new BlogInfo(heads[1], heads[2]);
    }

    /**
     * 获取当前博文头部标题等信息
     */
    public static BlogTitle getBlogTitle(BlogInfo blogInfo) {
        String[] split = blogInfo.getMdHeadInfo().split("\n");
        BlogTitle blogTitle = new BlogTitle();
        Stream.of(split)
                .filter(v -> StringUtils.isNotBlank(v))
                .peek(log::info)
                .forEach(value -> blogTitle.set(value));
        Assert.hasLength(blogTitle.getTitle(), "标题为空");
        Assert.hasLength(blogTitle.getCanonical_url(), "canonical_url不能为空");
        long now = System.currentTimeMillis();
        blogTitle.setAddTime(now);
        blogTitle.setUpdateTime(now);
        blogTitle.setAddTimeStr(DateHelper.getCurrentDateTime(DateHelper.DATE_FORMAT_CHINESE));
        blogTitle.setUrlPath("/wiki/" + blogTitle.getCanonical_url());
        blogTitle.setMdLink("[" + blogTitle.getTitle() + "](" + blogTitle.getUrlPath() + ")");
        log.info("getBlogTitle ===> blogTitle :{}", blogTitle.toString());
        return blogTitle;
    }

    /**
     * 更新文章列表JSON
     */
    public static List<BlogTitle> updateBlogListJson(BlogTitle blogTitle) throws IOException {
        File file = FileHelper.getFile("data/home-blog-list.json");
        String json = IOUtils.toString(file.toURI(), Charset.forName("utf-8"));
        LinkedList<BlogTitle> blogTitles = new LinkedList();
        if (StringUtils.isNotBlank(json)) {
            blogTitles.addAll(JSON.parseArray(json, BlogTitle.class));
        }
        boolean exit = false;
        for (BlogTitle title : blogTitles) {
            if (title.getCanonical_url().equals(blogTitle.getCanonical_url())) {
                title.setTitle(blogTitle.getTitle());
                title.setTagList(blogTitle.getTagList());
                title.setDescription(blogTitle.getDescription());
                title.setCover_image(blogTitle.getCover_image());
                exit = true;
                break;
            }
        }
        if (!exit) {
            blogTitles.addFirst(blogTitle);
        }
        FileUtils.writeStringToFile(file, JSON.toJSONString(blogTitles), Charset.forName("utf-8"));
        log.info("updateBlogListJson ===> title :{}", blogTitle.getTitle());
        return blogTitles;
    }

    /**
     * 创建博文内容Markdown对应的HTML
     */
    public static void createBlogHtmlFile(BlogTitle blogTitle, BlogInfo blogInfo) throws Exception {
        FileUtils.forceMkdir(new File("wiki/" + blogTitle.getCanonical_url()));
        String html = MarkdownParser.getHTML(blogInfo.getMdContent());
        Map<String, Object> paramMap = new HashMap<>(2);
        paramMap.put("blogTitle", blogTitle);
        paramMap.put("markdown-html", html);
        String newIndexPath = "wiki/" + blogTitle.getCanonical_url() + "/index.html";
        File indexHtmlFile = new File(newIndexPath);
        String htmlString = VelocityHelper.getHtmlString(getTemplate(Constants.BLOG_PAGE_TEMPLATE), paramMap);
        FileUtils.writeStringToFile(indexHtmlFile, htmlString, Charset.forName("utf-8"));
        log.info("createBlogHtmlFile ===> blogTitle :{}  newIndexPath:{}", blogTitle.getTitle(), newIndexPath);
    }

    /**
     * 更新wiki首页内容
     */
    public static void updateBlogHomeHtml(List<BlogTitle> blogTitles) throws Exception {
        File homeTemplate = new File("assets/template/blog-home.vm");
        String homeTemplateStr = IOUtils.toString(homeTemplate.toURI(), Charset.forName("utf-8"));
        Map<String, Object> paramMap = new HashMap<>(1);
        paramMap.put("blogTitles", blogTitles);
        String htmlString = VelocityHelper.getHtmlString(getTemplate(Constants.BLOG_HOME_TEMPLATE), paramMap);
        File homePage = new File("index.html");
        FileUtils.writeStringToFile(homePage, htmlString, Charset.forName("utf-8"));
        log.info("updateBlogHomeHtml ===> success size:{}", blogTitles.size());
    }

    /**
     * 更新侧边栏
     */
    public static void updateDirectory() throws Exception {
        File READMEFile = new File("README.md");
        String md = IOUtils.toString(READMEFile.toURI(), Charset.forName("utf-8"));
        String html = MarkdownParser.getHTML(md);
        String htmlCompress = HtmlHelper.htmlCompress(html);
        String encodeToString = Base64Utils.encodeToString(htmlCompress.getBytes());
        Map<String, Object> paramMap = new HashMap<>(1);
        paramMap.put("directoryData", encodeToString);
        String data = VelocityHelper.getHtmlString(getTemplate(Constants.BLOG_DIC_TEMPLATE), paramMap);
        File directoryJsFile = new File("data/directory.js");
        FileUtils.writeStringToFile(directoryJsFile, data, Charset.forName("utf-8"));
        log.info("updateDirectory ===> success ");
    }


    public static String getTemplate(String templateName) throws IOException {
        File file = FileHelper.getFile("assets/template/" + templateName);
        return IOUtils.toString(file.toURI(), Charset.forName("utf-8"));
    }

}
